package com.etc.utils;


import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.Charset;


public class FtpUtil {

   private static Logger log = LoggerFactory.getLogger(FtpUtil.class);

    /**
     *
     本地编码集对象
     */
    private static String encode = Charset.defaultCharset().toString();

    // FTP编码为iso-8859-1
    private static final String SERVER_CHARSET = "ISO-8859-1";

    //FTP下载时读入内存的大小
    private static final int BUFFER_SIZE = 1024000;


    /**
     * 获取FTP连接对象，连接FTP成功返回FTP对象，
     * 连接FTP失败超过最大次数返回null,使用前请判断是否为空
     * @param ftpHost 服务器ip
     * @param ftpPort 服务器端口
     * @param ftpUserName 用户名
     * @param ftpPassword 密码
     * @return FTPClient FTP连接对象
     */
    public static FTPClient getFTPClient(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword) {

        //FTP连接对象
        FTPClient ftpClient = null;

        try
        {
            ftpClient = new FTPClient();
            //设置FTP服务器IP和端口
            ftpClient.connect(ftpHost,ftpPort);
            //设置超时时间,毫秒
            ftpClient.setConnectTimeout(50000);
            //登录FTP
            ftpClient.login(ftpUserName,ftpPassword);

            //设置被动传输模式
            ftpClient.enterLocalPassiveMode();
            //ftpClient.enterRemotePassiveMode();
            //二进制传输
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            //设置读入内存文件大小
            ftpClient.setBufferSize(BUFFER_SIZE);

            //获取FTP连接状态码 ，大于等于200 小于300状态码表示连接正常
            int connectState = ftpClient.getReplyCode();

            //连接失败重试
            int reNum = 0;
            while (!FTPReply.isPositiveCompletion(connectState)
                    && reNum < 3)
            {
                ftpClient.disconnect();
                ++reNum;
                ftpClient.login(ftpUserName,ftpPassword);

            }
            if (reNum < 3) {

                log.info("FTP连接成功");

            } else {
                ftpClient = null;
                log.error("FTP连接失败");
            }

        } catch (Exception e)
        {

            log.error(e.getMessage(), e);
        }

        return ftpClient;
    }

    /**
     *断开FTP
     * @param ftpClient fpt连接对象
     */
    public static void closeFTP(FTPClient ftpClient) {

        if (null != ftpClient) {
            try {
                //登出FTP
                ftpClient.disconnect();
                log.info("登出FTP成功");
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            } finally {
                try {
                    //断开FTP
                    ftpClient.disconnect();
                    log.info("断开FTP成功");
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }

        }
    }


    /**
     * 根据FTP编码集转换文件路径，防止中文乱码，并设置FTP连接的编码集
     * @param ftpClient FTP连接对象
     * @param path 文件路径
     * @return 转码后的文件路径
     */
    public static String changeEncode(FTPClient ftpClient,String path) throws IOException
    {
        synchronized (encode)
        {
            int status = ftpClient.sendCommand("OPTS UTF8","ON");
            //判断FTP服务器是否支持UTF -8,支持使用UTF-8 否则使用本地编码集
            if(FTPReply.isPositiveCompletion(status))
            {
                encode = "UTF-8";
            }

            log.info("FTP使用编码集：" + encode);

            ftpClient.setControlEncoding(encode);
            path = new String(path.getBytes(encode),SERVER_CHARSET);
        }

        return path;
    }

    /**
     * 获取文件后缀
     * @param fileName 文件名或文件全路径
     * @return 文件后缀
     */
    public static String getSuffix(String fileName)
    {
        String suffix = "";

        int index = fileName.lastIndexOf(".");
        if(index != -1)
        {
            suffix = fileName.substring(index);
            log.info("获取文件后缀名成功，文件名：" + fileName + " 后缀名：" + suffix);
        }else{
            log.warn("获取文件后缀名失败,文件名" + fileName);
        }
        return suffix;
    }


    /**
     * FTP文件上传工具类
     * @param ftpClient 连接对象
     * @param ftpPath ftp储存路径
     * @param newFileName ftp保存的文件名
     * @return true 下载成功，false 下载失败
     */
    public static boolean uploadFile(FTPClient ftpClient,InputStream in,String ftpPath, String newFileName)
    {
        boolean flag = false;
        try {
            //路径转码，处理中文
            ftpPath = changeEncode(ftpClient,ftpPath);
            newFileName = changeEncode(ftpClient,newFileName);
            //判断目标文件夹是否存在,不存在就创建
            if(!ftpClient.changeWorkingDirectory(ftpPath)) {
                ftpClient.makeDirectory(ftpPath);
                ftpClient.changeWorkingDirectory(ftpPath);
            }
            //上传文件
            flag = ftpClient.storeFile(newFileName,in);
            if(flag) {
                log.info("文件上传成功：" + newFileName);
            }
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        } finally {
            try {
                if(in != null) {
                    in.close();
                }
            } catch (IOException e) {
                log.error(e.getMessage(),e);
            }
        }
        return flag;
    }

}
